home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / xml / etree / ElementTree.pyo (.txt) < prev   
Python Compiled Bytecode  |  2008-10-13  |  24KB  |  887 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __all__ = [
  5.     'Comment',
  6.     'dump',
  7.     'Element',
  8.     'ElementTree',
  9.     'fromstring',
  10.     'iselement',
  11.     'iterparse',
  12.     'parse',
  13.     'PI',
  14.     'ProcessingInstruction',
  15.     'QName',
  16.     'SubElement',
  17.     'tostring',
  18.     'TreeBuilder',
  19.     'VERSION',
  20.     'XML',
  21.     'XMLParser',
  22.     'XMLTreeBuilder']
  23. import string
  24. import sys
  25. import re
  26.  
  27. class _SimpleElementPath:
  28.     
  29.     def find(self, element, tag):
  30.         for elem in element:
  31.             if elem.tag == tag:
  32.                 return elem
  33.                 continue
  34.         
  35.  
  36.     
  37.     def findtext(self, element, tag, default = None):
  38.         for elem in element:
  39.             if elem.tag == tag:
  40.                 if not elem.text:
  41.                     pass
  42.                 return ''
  43.                 continue
  44.         
  45.         return default
  46.  
  47.     
  48.     def findall(self, element, tag):
  49.         if tag[:3] == './/':
  50.             return element.getiterator(tag[3:])
  51.         
  52.         result = []
  53.         for elem in element:
  54.             if elem.tag == tag:
  55.                 result.append(elem)
  56.                 continue
  57.         
  58.         return result
  59.  
  60.  
  61.  
  62. try:
  63.     import ElementPath
  64. except ImportError:
  65.     ElementPath = _SimpleElementPath()
  66.  
  67. VERSION = '1.2.6'
  68.  
  69. class _ElementInterface:
  70.     tag = None
  71.     attrib = None
  72.     text = None
  73.     tail = None
  74.     
  75.     def __init__(self, tag, attrib):
  76.         self.tag = tag
  77.         self.attrib = attrib
  78.         self._children = []
  79.  
  80.     
  81.     def __repr__(self):
  82.         return '<Element %s at %x>' % (self.tag, id(self))
  83.  
  84.     
  85.     def makeelement(self, tag, attrib):
  86.         return Element(tag, attrib)
  87.  
  88.     
  89.     def __len__(self):
  90.         return len(self._children)
  91.  
  92.     
  93.     def __getitem__(self, index):
  94.         return self._children[index]
  95.  
  96.     
  97.     def __setitem__(self, index, element):
  98.         self._children[index] = element
  99.  
  100.     
  101.     def __delitem__(self, index):
  102.         del self._children[index]
  103.  
  104.     
  105.     def __getslice__(self, start, stop):
  106.         return self._children[start:stop]
  107.  
  108.     
  109.     def __setslice__(self, start, stop, elements):
  110.         for element in elements:
  111.             pass
  112.         
  113.         self._children[start:stop] = list(elements)
  114.  
  115.     
  116.     def __delslice__(self, start, stop):
  117.         del self._children[start:stop]
  118.  
  119.     
  120.     def append(self, element):
  121.         self._children.append(element)
  122.  
  123.     
  124.     def insert(self, index, element):
  125.         self._children.insert(index, element)
  126.  
  127.     
  128.     def remove(self, element):
  129.         self._children.remove(element)
  130.  
  131.     
  132.     def getchildren(self):
  133.         return self._children
  134.  
  135.     
  136.     def find(self, path):
  137.         return ElementPath.find(self, path)
  138.  
  139.     
  140.     def findtext(self, path, default = None):
  141.         return ElementPath.findtext(self, path, default)
  142.  
  143.     
  144.     def findall(self, path):
  145.         return ElementPath.findall(self, path)
  146.  
  147.     
  148.     def clear(self):
  149.         self.attrib.clear()
  150.         self._children = []
  151.         self.text = None
  152.         self.tail = None
  153.  
  154.     
  155.     def get(self, key, default = None):
  156.         return self.attrib.get(key, default)
  157.  
  158.     
  159.     def set(self, key, value):
  160.         self.attrib[key] = value
  161.  
  162.     
  163.     def keys(self):
  164.         return self.attrib.keys()
  165.  
  166.     
  167.     def items(self):
  168.         return self.attrib.items()
  169.  
  170.     
  171.     def getiterator(self, tag = None):
  172.         nodes = []
  173.         if tag == '*':
  174.             tag = None
  175.         
  176.         if tag is None or self.tag == tag:
  177.             nodes.append(self)
  178.         
  179.         for node in self._children:
  180.             nodes.extend(node.getiterator(tag))
  181.         
  182.         return nodes
  183.  
  184.  
  185. _Element = _ElementInterface
  186.  
  187. def Element(tag, attrib = { }, **extra):
  188.     attrib = attrib.copy()
  189.     attrib.update(extra)
  190.     return _ElementInterface(tag, attrib)
  191.  
  192.  
  193. def SubElement(parent, tag, attrib = { }, **extra):
  194.     attrib = attrib.copy()
  195.     attrib.update(extra)
  196.     element = parent.makeelement(tag, attrib)
  197.     parent.append(element)
  198.     return element
  199.  
  200.  
  201. def Comment(text = None):
  202.     element = Element(Comment)
  203.     element.text = text
  204.     return element
  205.  
  206.  
  207. def ProcessingInstruction(target, text = None):
  208.     element = Element(ProcessingInstruction)
  209.     element.text = target
  210.     if text:
  211.         element.text = element.text + ' ' + text
  212.     
  213.     return element
  214.  
  215. PI = ProcessingInstruction
  216.  
  217. class QName:
  218.     
  219.     def __init__(self, text_or_uri, tag = None):
  220.         if tag:
  221.             text_or_uri = '{%s}%s' % (text_or_uri, tag)
  222.         
  223.         self.text = text_or_uri
  224.  
  225.     
  226.     def __str__(self):
  227.         return self.text
  228.  
  229.     
  230.     def __hash__(self):
  231.         return hash(self.text)
  232.  
  233.     
  234.     def __cmp__(self, other):
  235.         if isinstance(other, QName):
  236.             return cmp(self.text, other.text)
  237.         
  238.         return cmp(self.text, other)
  239.  
  240.  
  241.  
  242. class ElementTree:
  243.     
  244.     def __init__(self, element = None, file = None):
  245.         self._root = element
  246.         if file:
  247.             self.parse(file)
  248.         
  249.  
  250.     
  251.     def getroot(self):
  252.         return self._root
  253.  
  254.     
  255.     def _setroot(self, element):
  256.         self._root = element
  257.  
  258.     
  259.     def parse(self, source, parser = None):
  260.         if not hasattr(source, 'read'):
  261.             source = open(source, 'rb')
  262.         
  263.         if not parser:
  264.             parser = XMLTreeBuilder()
  265.         
  266.         while None:
  267.             data = source.read(32768)
  268.             if not data:
  269.                 break
  270.             
  271.             continue
  272.             self._root = parser.close()
  273.             return self._root
  274.  
  275.     
  276.     def getiterator(self, tag = None):
  277.         return self._root.getiterator(tag)
  278.  
  279.     
  280.     def find(self, path):
  281.         if path[:1] == '/':
  282.             path = '.' + path
  283.         
  284.         return self._root.find(path)
  285.  
  286.     
  287.     def findtext(self, path, default = None):
  288.         if path[:1] == '/':
  289.             path = '.' + path
  290.         
  291.         return self._root.findtext(path, default)
  292.  
  293.     
  294.     def findall(self, path):
  295.         if path[:1] == '/':
  296.             path = '.' + path
  297.         
  298.         return self._root.findall(path)
  299.  
  300.     
  301.     def write(self, file, encoding = 'us-ascii'):
  302.         if not hasattr(file, 'write'):
  303.             file = open(file, 'wb')
  304.         
  305.         if not encoding:
  306.             encoding = 'us-ascii'
  307.         elif encoding != 'utf-8' and encoding != 'us-ascii':
  308.             file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding)
  309.         
  310.         self._write(file, self._root, encoding, { })
  311.  
  312.     
  313.     def _write(self, file, node, encoding, namespaces):
  314.         tag = node.tag
  315.         if tag is Comment:
  316.             file.write('<!-- %s -->' % _escape_cdata(node.text, encoding))
  317.         elif tag is ProcessingInstruction:
  318.             file.write('<?%s?>' % _escape_cdata(node.text, encoding))
  319.         else:
  320.             items = node.items()
  321.             xmlns_items = []
  322.             
  323.             try:
  324.                 if isinstance(tag, QName) or tag[:1] == '{':
  325.                     (tag, xmlns) = fixtag(tag, namespaces)
  326.                     if xmlns:
  327.                         xmlns_items.append(xmlns)
  328.                     
  329.             except TypeError:
  330.                 _raise_serialization_error(tag)
  331.  
  332.             file.write('<' + _encode(tag, encoding))
  333.             if items or xmlns_items:
  334.                 items.sort()
  335.                 for k, v in items:
  336.                     
  337.                     try:
  338.                         if isinstance(k, QName) or k[:1] == '{':
  339.                             (k, xmlns) = fixtag(k, namespaces)
  340.                             if xmlns:
  341.                                 xmlns_items.append(xmlns)
  342.                             
  343.                     except TypeError:
  344.                         _raise_serialization_error(k)
  345.  
  346.                     
  347.                     try:
  348.                         if isinstance(v, QName):
  349.                             (v, xmlns) = fixtag(v, namespaces)
  350.                             if xmlns:
  351.                                 xmlns_items.append(xmlns)
  352.                             
  353.                     except TypeError:
  354.                         _raise_serialization_error(v)
  355.  
  356.                     file.write(' %s="%s"' % (_encode(k, encoding), _escape_attrib(v, encoding)))
  357.                 
  358.                 for k, v in xmlns_items:
  359.                     file.write(' %s="%s"' % (_encode(k, encoding), _escape_attrib(v, encoding)))
  360.                 
  361.             
  362.             if node.text or len(node):
  363.                 file.write('>')
  364.                 if node.text:
  365.                     file.write(_escape_cdata(node.text, encoding))
  366.                 
  367.                 for n in node:
  368.                     self._write(file, n, encoding, namespaces)
  369.                 
  370.                 file.write('</' + _encode(tag, encoding) + '>')
  371.             else:
  372.                 file.write(' />')
  373.             for k, v in xmlns_items:
  374.                 del namespaces[v]
  375.             
  376.         if node.tail:
  377.             file.write(_escape_cdata(node.tail, encoding))
  378.         
  379.  
  380.  
  381.  
  382. def iselement(element):
  383.     if not isinstance(element, _ElementInterface):
  384.         pass
  385.     return hasattr(element, 'tag')
  386.  
  387.  
  388. def dump(elem):
  389.     if not isinstance(elem, ElementTree):
  390.         elem = ElementTree(elem)
  391.     
  392.     elem.write(sys.stdout)
  393.     tail = elem.getroot().tail
  394.     if not tail or tail[-1] != '\n':
  395.         sys.stdout.write('\n')
  396.     
  397.  
  398.  
  399. def _encode(s, encoding):
  400.     
  401.     try:
  402.         return s.encode(encoding)
  403.     except AttributeError:
  404.         return s
  405.  
  406.  
  407. if sys.version[:3] == '1.5':
  408.     _escape = re.compile('[&<>\\"\\x80-\\xff]+')
  409. else:
  410.     _escape = re.compile(eval('u"[&<>\\"\\u0080-\\uffff]+"'))
  411. _escape_map = {
  412.     '&': '&',
  413.     '<': '<',
  414.     '>': '>',
  415.     '"': '"' }
  416. _namespace_map = {
  417.     'http://www.w3.org/XML/1998/namespace': 'xml',
  418.     'http://www.w3.org/1999/xhtml': 'html',
  419.     'http://www.w3.org/1999/02/22-rdf-syntax-ns#': 'rdf',
  420.     'http://schemas.xmlsoap.org/wsdl/': 'wsdl' }
  421.  
  422. def _raise_serialization_error(text):
  423.     raise TypeError('cannot serialize %r (type %s)' % (text, type(text).__name__))
  424.  
  425.  
  426. def _encode_entity(text, pattern = _escape):
  427.     
  428.     def escape_entities(m, map = _escape_map):
  429.         out = []
  430.         append = out.append
  431.         for char in m.group():
  432.             text = map.get(char)
  433.             if text is None:
  434.                 text = '&#%d;' % ord(char)
  435.             
  436.             append(text)
  437.         
  438.         return string.join(out, '')
  439.  
  440.     
  441.     try:
  442.         return _encode(pattern.sub(escape_entities, text), 'ascii')
  443.     except TypeError:
  444.         _raise_serialization_error(text)
  445.  
  446.  
  447.  
  448. def _escape_cdata(text, encoding = None, replace = string.replace):
  449.     
  450.     try:
  451.         if encoding:
  452.             
  453.             try:
  454.                 text = _encode(text, encoding)
  455.             except UnicodeError:
  456.                 return _encode_entity(text)
  457.             except:
  458.                 None<EXCEPTION MATCH>UnicodeError
  459.             
  460.  
  461.         None<EXCEPTION MATCH>UnicodeError
  462.         text = replace(text, '&', '&')
  463.         text = replace(text, '<', '<')
  464.         text = replace(text, '>', '>')
  465.         return text
  466.     except (TypeError, AttributeError):
  467.         _raise_serialization_error(text)
  468.  
  469.  
  470.  
  471. def _escape_attrib(text, encoding = None, replace = string.replace):
  472.     
  473.     try:
  474.         if encoding:
  475.             
  476.             try:
  477.                 text = _encode(text, encoding)
  478.             except UnicodeError:
  479.                 return _encode_entity(text)
  480.             except:
  481.                 None<EXCEPTION MATCH>UnicodeError
  482.             
  483.  
  484.         None<EXCEPTION MATCH>UnicodeError
  485.         text = replace(text, '&', '&')
  486.         text = replace(text, "'", ''')
  487.         text = replace(text, '"', '"')
  488.         text = replace(text, '<', '<')
  489.         text = replace(text, '>', '>')
  490.         return text
  491.     except (TypeError, AttributeError):
  492.         _raise_serialization_error(text)
  493.  
  494.  
  495.  
  496. def fixtag(tag, namespaces):
  497.     if isinstance(tag, QName):
  498.         tag = tag.text
  499.     
  500.     (namespace_uri, tag) = string.split(tag[1:], '}', 1)
  501.     prefix = namespaces.get(namespace_uri)
  502.     if prefix is None:
  503.         prefix = _namespace_map.get(namespace_uri)
  504.         if prefix is None:
  505.             prefix = 'ns%d' % len(namespaces)
  506.         
  507.         namespaces[namespace_uri] = prefix
  508.         if prefix == 'xml':
  509.             xmlns = None
  510.         else:
  511.             xmlns = ('xmlns:%s' % prefix, namespace_uri)
  512.     else:
  513.         xmlns = None
  514.     return ('%s:%s' % (prefix, tag), xmlns)
  515.  
  516.  
  517. def parse(source, parser = None):
  518.     tree = ElementTree()
  519.     tree.parse(source, parser)
  520.     return tree
  521.  
  522.  
  523. class iterparse:
  524.     
  525.     def __init__(self, source, events = None):
  526.         if not hasattr(source, 'read'):
  527.             source = open(source, 'rb')
  528.         
  529.         self._file = source
  530.         self._events = []
  531.         self._index = 0
  532.         self.root = None
  533.         self._root = None
  534.         self._parser = XMLTreeBuilder()
  535.         parser = self._parser._parser
  536.         append = self._events.append
  537.         if events is None:
  538.             events = [
  539.                 'end']
  540.         
  541.         for event in events:
  542.             if event == 'start':
  543.                 
  544.                 try:
  545.                     parser.ordered_attributes = 1
  546.                     parser.specified_attributes = 1
  547.                     
  548.                     def handler(tag, attrib_in, event = event, append = append, start = self._parser._start_list):
  549.                         append((event, start(tag, attrib_in)))
  550.  
  551.                     parser.StartElementHandler = handler
  552.                 except AttributeError:
  553.                     
  554.                     def handler(tag, attrib_in, event = event, append = append, start = self._parser._start):
  555.                         append((event, start(tag, attrib_in)))
  556.  
  557.                     parser.StartElementHandler = handler
  558.                 except:
  559.                     None<EXCEPTION MATCH>AttributeError
  560.                 
  561.  
  562.             None<EXCEPTION MATCH>AttributeError
  563.             if event == 'end':
  564.                 
  565.                 def handler(tag, event = event, append = append, end = self._parser._end):
  566.                     append((event, end(tag)))
  567.  
  568.                 parser.EndElementHandler = handler
  569.                 continue
  570.             if event == 'start-ns':
  571.                 
  572.                 def handler(prefix, uri, event = event, append = append):
  573.                     
  574.                     try:
  575.                         uri = _encode(uri, 'ascii')
  576.                     except UnicodeError:
  577.                         pass
  578.  
  579.                     if not prefix:
  580.                         pass
  581.                     append((event, ('', uri)))
  582.  
  583.                 parser.StartNamespaceDeclHandler = handler
  584.                 continue
  585.             if event == 'end-ns':
  586.                 
  587.                 def handler(prefix, event = event, append = append):
  588.                     append((event, None))
  589.  
  590.                 parser.EndNamespaceDeclHandler = handler
  591.                 continue
  592.         
  593.  
  594.     
  595.     def next(self):
  596.         while None:
  597.             
  598.             try:
  599.                 item = self._events[self._index]
  600.             except IndexError:
  601.                 if self._parser is None:
  602.                     self.root = self._root
  603.                     
  604.                     try:
  605.                         raise StopIteration
  606.                     except NameError:
  607.                         raise IndexError
  608.                     except:
  609.                         None<EXCEPTION MATCH>NameError
  610.                     
  611.  
  612.                 None<EXCEPTION MATCH>NameError
  613.                 del self._events[:]
  614.                 self._index = 0
  615.                 data = self._file.read(16384)
  616.                 if data:
  617.                     self._parser.feed(data)
  618.                 else:
  619.                     self._root = self._parser.close()
  620.                     self._parser = None
  621.                 data
  622.  
  623.             self._index = self._index + 1
  624.             return item
  625.             continue
  626.             return None
  627.  
  628.     
  629.     try:
  630.         iter
  631.         
  632.         def __iter__(self):
  633.             return self
  634.  
  635.     except NameError:
  636.         
  637.         def __getitem__(self, index):
  638.             return self.next()
  639.  
  640.  
  641.  
  642.  
  643. def XML(text):
  644.     parser = XMLTreeBuilder()
  645.     parser.feed(text)
  646.     return parser.close()
  647.  
  648.  
  649. def XMLID(text):
  650.     parser = XMLTreeBuilder()
  651.     parser.feed(text)
  652.     tree = parser.close()
  653.     ids = { }
  654.     for elem in tree.getiterator():
  655.         id = elem.get('id')
  656.         if id:
  657.             ids[id] = elem
  658.             continue
  659.     
  660.     return (tree, ids)
  661.  
  662. fromstring = XML
  663.  
  664. def tostring(element, encoding = None):
  665.     
  666.     class dummy:
  667.         pass
  668.  
  669.     data = []
  670.     file = dummy()
  671.     file.write = data.append
  672.     ElementTree(element).write(file, encoding)
  673.     return string.join(data, '')
  674.  
  675.  
  676. class TreeBuilder:
  677.     
  678.     def __init__(self, element_factory = None):
  679.         self._data = []
  680.         self._elem = []
  681.         self._last = None
  682.         self._tail = None
  683.         if element_factory is None:
  684.             element_factory = _ElementInterface
  685.         
  686.         self._factory = element_factory
  687.  
  688.     
  689.     def close(self):
  690.         return self._last
  691.  
  692.     
  693.     def _flush(self):
  694.         if self._data:
  695.             if self._last is not None:
  696.                 text = string.join(self._data, '')
  697.                 if self._tail:
  698.                     self._last.tail = text
  699.                 else:
  700.                     self._last.text = text
  701.             
  702.             self._data = []
  703.         
  704.  
  705.     
  706.     def data(self, data):
  707.         self._data.append(data)
  708.  
  709.     
  710.     def start(self, tag, attrs):
  711.         self._flush()
  712.         self._last = elem = self._factory(tag, attrs)
  713.         if self._elem:
  714.             self._elem[-1].append(elem)
  715.         
  716.         self._elem.append(elem)
  717.         self._tail = 0
  718.         return elem
  719.  
  720.     
  721.     def end(self, tag):
  722.         self._flush()
  723.         self._last = self._elem.pop()
  724.         self._tail = 1
  725.         return self._last
  726.  
  727.  
  728.  
  729. class XMLTreeBuilder:
  730.     
  731.     def __init__(self, html = 0, target = None):
  732.         
  733.         try:
  734.             expat = expat
  735.             import xml.parsers
  736.         except ImportError:
  737.             raise ImportError('No module named expat; use SimpleXMLTreeBuilder instead')
  738.  
  739.         self._parser = parser = expat.ParserCreate(None, '}')
  740.         if target is None:
  741.             target = TreeBuilder()
  742.         
  743.         self._target = target
  744.         self._names = { }
  745.         parser.DefaultHandlerExpand = self._default
  746.         parser.StartElementHandler = self._start
  747.         parser.EndElementHandler = self._end
  748.         parser.CharacterDataHandler = self._data
  749.         
  750.         try:
  751.             self._parser.buffer_text = 1
  752.         except AttributeError:
  753.             pass
  754.  
  755.         
  756.         try:
  757.             self._parser.ordered_attributes = 1
  758.             self._parser.specified_attributes = 1
  759.             parser.StartElementHandler = self._start_list
  760.         except AttributeError:
  761.             pass
  762.  
  763.         encoding = None
  764.         if not parser.returns_unicode:
  765.             encoding = 'utf-8'
  766.         
  767.         self._doctype = None
  768.         self.entity = { }
  769.  
  770.     
  771.     def _fixtext(self, text):
  772.         
  773.         try:
  774.             return _encode(text, 'ascii')
  775.         except UnicodeError:
  776.             return text
  777.  
  778.  
  779.     
  780.     def _fixname(self, key):
  781.         
  782.         try:
  783.             name = self._names[key]
  784.         except KeyError:
  785.             name = key
  786.             if '}' in name:
  787.                 name = '{' + name
  788.             
  789.             self._names[key] = name = self._fixtext(name)
  790.  
  791.         return name
  792.  
  793.     
  794.     def _start(self, tag, attrib_in):
  795.         fixname = self._fixname
  796.         tag = fixname(tag)
  797.         attrib = { }
  798.         for key, value in attrib_in.items():
  799.             attrib[fixname(key)] = self._fixtext(value)
  800.         
  801.         return self._target.start(tag, attrib)
  802.  
  803.     
  804.     def _start_list(self, tag, attrib_in):
  805.         fixname = self._fixname
  806.         tag = fixname(tag)
  807.         attrib = { }
  808.         if attrib_in:
  809.             for i in range(0, len(attrib_in), 2):
  810.                 attrib[fixname(attrib_in[i])] = self._fixtext(attrib_in[i + 1])
  811.             
  812.         
  813.         return self._target.start(tag, attrib)
  814.  
  815.     
  816.     def _data(self, text):
  817.         return self._target.data(self._fixtext(text))
  818.  
  819.     
  820.     def _end(self, tag):
  821.         return self._target.end(self._fixname(tag))
  822.  
  823.     
  824.     def _default(self, text):
  825.         prefix = text[:1]
  826.         if prefix == '&':
  827.             
  828.             try:
  829.                 self._target.data(self.entity[text[1:-1]])
  830.             except KeyError:
  831.                 expat = expat
  832.                 import xml.parsers
  833.                 raise expat.error('undefined entity %s: line %d, column %d' % (text, self._parser.ErrorLineNumber, self._parser.ErrorColumnNumber))
  834.             except:
  835.                 None<EXCEPTION MATCH>KeyError
  836.             
  837.  
  838.         None<EXCEPTION MATCH>KeyError
  839.         if prefix == '<' and text[:9] == '<!DOCTYPE':
  840.             self._doctype = []
  841.         elif self._doctype is not None:
  842.             if prefix == '>':
  843.                 self._doctype = None
  844.                 return None
  845.             
  846.             text = string.strip(text)
  847.             if not text:
  848.                 return None
  849.             
  850.             self._doctype.append(text)
  851.             n = len(self._doctype)
  852.             if n > 2:
  853.                 type = self._doctype[1]
  854.                 if type == 'PUBLIC' and n == 4:
  855.                     (name, type, pubid, system) = self._doctype
  856.                 elif type == 'SYSTEM' and n == 3:
  857.                     (name, type, system) = self._doctype
  858.                     pubid = None
  859.                 else:
  860.                     return None
  861.                 if pubid:
  862.                     pubid = pubid[1:-1]
  863.                 
  864.                 self.doctype(name, pubid, system[1:-1])
  865.                 self._doctype = None
  866.             
  867.         
  868.  
  869.     
  870.     def doctype(self, name, pubid, system):
  871.         pass
  872.  
  873.     
  874.     def feed(self, data):
  875.         self._parser.Parse(data, 0)
  876.  
  877.     
  878.     def close(self):
  879.         self._parser.Parse('', 1)
  880.         tree = self._target.close()
  881.         del self._target
  882.         del self._parser
  883.         return tree
  884.  
  885.  
  886. XMLParser = XMLTreeBuilder
  887.